//*************************************************************************//
//*           _____   ____________            ______               __     *//
//*          / /__ \ / ____/ ____/           / ____/___  _________/ /     *//
//*     __  / /__/ // __/ / __/    ______   / /_  / __ \/ ___/ __  /      *//
//*    / /_/ // __// /___/ /___   /_____/  / __/ / /_/ / /  / /_/ /       *//
//*    \____//____/_____/_____/           /_/    \____/_/   \__,_/        *//
//*                                                                       *//
//*     Copyright (c) 2006 Ford Argentina. All Rights Reserved.           *//
//*                                                                       *//
//*************************************************************************//

package ar.com.ford.it.webengine.struts.jstl.tag;

import java.io.IOException;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;
import org.apache.struts.taglib.html.Constants;
import org.apache.struts.taglib.html.FormTag;
import ar.com.ford.it.webengine.struts.TokenProcessor;
import com.ford.it.logging.ILogger;
import com.ford.it.logging.Level;
import com.ford.it.logging.LogFactory;

/**
 * SetFormTokenTag <br>
 * Custom tag that represents an html hidden input element storing a token value associated
 * to the current form Action. The rendered token is stored also in the current user's session.
 * 
 * @author Aji
 */
public class SetFormTokenTag extends TagSupport  {

    private static final String CLASS_NAME = SetFormTokenTag.class.getName();
    private static final ILogger log = LogFactory.getInstance().getLogger(CLASS_NAME);
    
    /**
     * Action asociated to the form. Only used when this tag is not inside an html:input tag.
     */
    private String action;

    /**
     * Constructor
     */
    public SetFormTokenTag() {
    }

    /**
     * Render the input tag.
     * @exception JspException if a JSP exception has occurred
     */
    public int doStartTag() throws JspException {
        String METHOD_NAME = "doStartTag";
        log.entering(CLASS_NAME, METHOD_NAME);
        Object formTag = pageContext.getRequest().getAttribute(Constants.FORM_KEY);
        ServletRequest request = pageContext.getRequest();
        // Buscar el Action definido en <html:form ...>
        if (formTag != null && formTag instanceof FormTag){
            action = ((FormTag)formTag).getAction();
        }
        else{
            log.logp(Level.FINE, CLASS_NAME, METHOD_NAME, "Html Tag: "+formTag);
        }
        
        log.logp(Level.FINE, CLASS_NAME, METHOD_NAME, "Action: "+action);
        
        // Si no se encontro el form se usa el atributo
        if (action!=null && request instanceof HttpServletRequest){
            if(!action.startsWith("/")){
                action = "/"+action;
            }
            this.printToken((HttpServletRequest)request, action);
        }
        else{
            if(action==null) {
                log.logp(Level.WARNING, CLASS_NAME, METHOD_NAME, "Token not setted: action attribute is null");
            }
            else{
                log.logp(Level.WARNING, CLASS_NAME, METHOD_NAME, "Token not setted: request "+request.getClass().getName());
            }
        }

        log.exiting(CLASS_NAME, METHOD_NAME);
        return SKIP_BODY;
    }

    /**
     * do nothing
     * @exception JspException if a JSP exception has occurred
     */
    public int doEndTag() throws JspException {
        String METHOD_NAME = "doEndTag";
        log.entering(CLASS_NAME, METHOD_NAME);

        log.exiting(CLASS_NAME, METHOD_NAME);
        return EVAL_PAGE;
    }

    /**
     * Render the input tag
     * @param action Action associated to the current form
     * @param request current user request
     * @exception JspException if a JSP exception has occurred
     */
    protected void printToken(HttpServletRequest request, String action) throws JspException{
        String METHOD_NAME = "printToken";
        log.entering(CLASS_NAME, METHOD_NAME, new Object[]{action, request});
        StringBuffer sb = new StringBuffer();
        String token = TokenProcessor.getInstance().saveToken(request, action);
        
        if (token!=null) {
            sb.append("<input type=\"hidden\" name=\"requestTOKEN\" value=\"");
            sb.append(token);
            sb.append("\"/>");
    
            JspWriter writer = pageContext.getOut();
            try {
                writer.print(sb.toString());
            } catch (IOException e) {
                JspException jspEx = new JspException(e.getMessage());
                jspEx.fillInStackTrace();
                throw jspEx;
            }
        }
        else{
            log.logp(Level.WARNING, CLASS_NAME, METHOD_NAME, "Token not generated for action "+action);
        }
        

        log.exiting(CLASS_NAME, METHOD_NAME);
    }

    /**
     * Setter for action
     * @param action action associated to the current form
     */
    public void setAction(String action) {
        this.action = action;
    }


    /**
     * Getter for action
     * @return action associated to the current form
     */
    public String getAction() {
        return action;
    }

}